# !/usr/bin/env python
# -*- coding: utf-8 -*-
"""
 -------------------------------------------------
    File Name:     base.py
    Description:   
 -------------------------------------------------
 """
import os
import sys
from argparse import ArgumentParser


# ALL_CHECKS = "__all__"

class CommandError(Exception):
    """
    异常类，表示执行管理命令时出现问题。

    如果在执行管理命令期间引发此异常，它将被捕获并转换为打印良好的错误信息，发送到相应的输出流（即 stderr）；
    因此，引发此异常（并附上合理的错误描述）是指示命令执行过程中出现问题的首选方式。
    """

    def __init__(self, *args, returncode=1, **kwargs):
        self.returncode = returncode
        super().__init__(*args, **kwargs)


class SystemCheckError(CommandError):
    """
    系统检查框架检测到不可恢复的错误.
    """

    pass


class CommandParser(ArgumentParser):
    """
    用于解析命令行参数的“ArgumentParser”的子类。

    自定义 ArgumentParser 类以改进一些错误消息并防止在多个场合出现SystemExit .
    因为当以编程方式调用命令时，SystemExit 是不可接受的。
    """

    def __init__(
            self, *, missing_args_message=None, called_from_command_line=None, **kwargs
    ):
        self.missing_args_message = missing_args_message
        self.called_from_command_line = called_from_command_line
        super().__init__(**kwargs)


class BaseCommand:
    """
    所有管理命令最终都从其派生而来的基类。
    """

    # 关于此命令的元数据。
    help = ""

    suppressed_base_arguments = set()

    def create_parser(self, prog_name, subcommand, **kwargs):
        """
        创建并返回用于解析此命令的参数的“ArgumentParser”。
        """
        # kwargs.setdefault("formatter_class", DjangoHelpFormatter)
        parser = CommandParser(
            prog="%s %s" % (os.path.basename(prog_name), subcommand),
            description=self.help or None,
            missing_args_message=getattr(self, "missing_args_message", None),
            called_from_command_line=getattr(self, "_called_from_command_line", None),
            **kwargs,
        )
        # self.add_base_argument(
        #     parser,
        #     "--version",
        #     action="version",
        #     version=self.get_version(),
        #     help="Show program's version number and exit.",
        # )
        self.add_arguments(parser)
        return parser

    def add_arguments(self, parser):
        """
        用于添加自定义参数的子类命令的入口点。
        """
        pass

    def add_base_argument(self, parser, *args, **kwargs):
        """
        调用解析器的 add_argument() 方法，根据 BaseCommand.suppressed_base_arguments 抑制帮助文本。
        """
        for arg in args:
            if arg in self.suppressed_base_arguments:
                kwargs["help"] = argparse.SUPPRESS
                break
        parser.add_argument(*args, **kwargs)

    def print_help(self, prog_name, subcommand):
        """
        打印该命令的帮助消息，源自“self.usage()”。
        """
        parser = self.create_parser(prog_name, subcommand)
        parser.print_help()

    def run_from_argv(self, argv):
        """
        设置任何请求的环境更改（例如，Python 路径和 Django 设置），然后运行此命令。
        如果命令引发“CommandError”，则拦截它并将其合理地打印到 stderr。
        如果存在“--traceback”选项或引发的“Exception”不是“CommandError”，则引发它。
        """
        parser = self.create_parser(argv[0], argv[1])

        options = parser.parse_args(argv[2:])
        cmd_options = vars(options)
        args = cmd_options.pop("args", ())

        try:
            self.execute(*args, **cmd_options)
        except CommandError as e:

            # if isinstance(e, SystemCheckError):
            #     self.std
            sys.exit(e.returncode)
        # finally:
        #     connection.close()

    def execute(self, *args, **options):
        """
        尝试执行此命令，如果需要，执行系统检查（由 ``requires_system_checks`` 属性控制，除非强制跳过）。
        """
        output = self.handle(*args, **options)

        return output

    def handle(self, *args, **options):
        """
        命令的实际逻辑。子类必须实现此方法。.
        """
        raise NotImplementedError(
            "BaseCommand 的子类必须提供 handle() 方法"
        )
